home *** CD-ROM | disk | FTP | other *** search
- # Source Generated with Decompyle++
- # File: in.pyo (Python 2.5)
-
- from __future__ import with_statement
- from collections import deque
- from threading import RLock
- from functools import wraps
- from pprint import pformat
-
- def lru_cache(maxsize):
- lck = RLock()
-
- def decorating_function(f):
- cache = { }
- queue = deque()
- refcount = { }
-
- def wrapper(*args, **kwargs):
- lck.__enter__()
-
- try:
- _cache = cache
- _len = len
- _refcount = refcount
- _maxsize = maxsize
- queue_append = queue.append
- queue_popleft = queue.popleft
- key = args
-
- try:
- result = _cache[key]
- except KeyError:
- lck
- lck
- result = _cache[key] = f(*args, **kwargs)
- except:
- lck
-
- queue_append(key)
- _refcount[key] = _refcount.get(key, 0) + 1
- while _len(_cache) > _maxsize:
- k = queue_popleft()
- _refcount[k] -= 1
- if not _refcount[k]:
- del _cache[k]
- del _refcount[k]
- continue
- lck
- if _len(queue) > _maxsize * 4:
- for i in [
- None] * _len(queue):
- k = queue_popleft()
- if _refcount[k] == 1:
- queue_append(k)
- continue
- _refcount[k] -= 1
-
- finally:
- pass
-
- return result
-
- wrapper = (None, None, None, None, None, wraps(f))(wrapper)
- return wrapper
-
- return decorating_function
-
-
- class MyDoublyLinkedListNode(object):
- __slots__ = [
- 'data',
- 'prev',
- 'next']
-
- def __init__(self, data, prev = None, next = None):
- self.data = data
- self.prev = prev
- self.next = next
-
-
- def remove(self):
- if self.prev is not None:
- self.prev.next = self.next
-
- self.next.prev = self.prev
-
-
- def append(self, node):
- if self.next is not None:
- raise NotImplmentedError("I don't have use for real insertion")
-
- self.next = node
- node.prev = self
-
-
- def __repr__(self):
- return '%s(%r, %r)' % (self.__class__.__name__, self.data, self.next)
-
-
-
- class LRU(dict):
-
- def __init__(self, limit):
- self._limit = limit
- self._ll_head = self._ll_last = MyDoublyLinkedListNode(None)
- self._ll_mapping = { }
- self.lock = RLock()
-
-
- def __setitem__(self, key, value):
- self.lock.__enter__()
-
- try:
- if self._ll_last.data == key:
- return dict.__setitem__(self, key, value)
-
- if key in self:
- self._ll_mapping[key].remove()
- elif len(self) == self._limit:
- self.pop_lru_key()
-
- new_node = MyDoublyLinkedListNode(key)
- self._ll_last.append(new_node)
- self._ll_last = new_node
- self._ll_mapping[key] = new_node
- dict.__setitem__(self, key, value)
- finally:
- pass
-
-
-
- def pop_lru_key(self):
- key = self._ll_head.next.data
- dict.__delitem__(self, key)
- del self._ll_mapping[key]
- self._ll_head.next.remove()
- return key
-
-
- def __delitem__(self, key):
- raise NotImplmentedError('Not necessary for LRU Cache')
-
-
- if __name__ == '__main__':
- c = LRU(3)
- print c
- c['a'] = 1
- c['b'] = 2
- c['c'] = 3
- print c
- c['c'] = 5
- print c
- c['a'] = 6
- print c
-
-